
#include "pop_win.h"

static pop_win_manage_t  pop_win;

static void pop_win_timer_callback(struct _lv_timer_t *t)
{
    //debug_d("pop win timeout\n");
    //pop_win_unload();
}

int pop_win_init(void)
{
    pop_win.len      = 0;
    pop_win.max_len  = 5;

    //*************************************************************/
    pop_win.e_head = (slist_t *)psram_malloc(sizeof(slist_t));
	if (pop_win.e_head == NULL) {
		l_d("e_head null\n");
		return -1;
	}
    slist_init(pop_win.e_head);
    //*************************************************************/
    pop_win.e_regist = (slist_t *)psram_malloc(sizeof(slist_t));
	if (pop_win.e_regist == NULL) {
		l_d("e_regist null\n");
		return -1;
	}
    slist_init(pop_win.e_regist);
    //*************************************************************/    
    pop_win.time = lv_timer_create(pop_win_timer_callback,6000,NULL);
    lv_timer_reset(pop_win.time);
    //************************************************************ */

    return 0;
}

int pop_win_destroy(void)
{
    int ret = -1;
    slist_t* node;
    pop_win_link_t * obj = NULL;

    if(!pop_win.e_head)
        return -1;

	slist_for_each(node, (pop_win.e_head))
	{
		obj = slist_entry(node,pop_win_link_t,e_tail);
		if(obj)
        {
            slist_remove(pop_win.e_head, &(obj->e_tail));
            pop_win.len--;
            psram_free(obj);
            obj = NULL;
		}
	}

    if(pop_win.e_head){
        psram_free(pop_win.e_head);
        pop_win.e_head = NULL;
    }

    return 0;
}

int pop_page_register(char * name,page_vtable_t *opt)
{
    int len = 0;
    pop_win_link_t * obj = NULL;

    if((!name)||(!opt)||(!pop_win.e_regist)){
        l_e("para err\n");
        return -1;
    }
    //*************************************************** */ 
    obj = (pop_win_link_t *)psram_malloc(sizeof(pop_win_link_t));
    if(obj == NULL){
        l_e("obj err\n");
        return -1;
    }
    memset(obj, 0, sizeof(pop_win_link_t));
    slist_init(&(obj->e_tail));  
    //**************************************************
    obj->e_attr.nav_bar       = NULL;
    obj->e_attr.root_event_cb = NULL;
    obj->e_attr.manager       = NULL;
    obj->e_attr.user_data     = NULL;
    obj->e_attr.priv.req_enable_cache       = 0;
    obj->e_attr.priv.req_disable_auto_cache = 0;
    obj->e_attr.priv.is_disable_auto_cache  = 0;
    obj->e_attr.priv.is_cached       = 0;
    obj->e_attr.priv.stash.ptr       = NULL;
    obj->e_attr.priv.stash.size      = 0;
    obj->e_attr.priv.state           = 0;
    obj->e_attr.priv.anim.is_enter   = 0;
    obj->e_attr.priv.anim.is_busy    = 0;
    obj->e_attr.priv.anim.attr.type  = 0;
    obj->e_attr.priv.anim.attr.time  = 0;
    obj->e_attr.priv.anim.attr.path  = NULL;
    //*************************************************** */  
    len = strlen(name) + 1;
    obj->e_attr.name = (char *)psram_malloc(len);
    if(obj->e_attr.name == NULL){
        l_e("name err\n");
        psram_free(obj);
        obj = NULL;
        return -1;
    }
    memset(obj->e_attr.name,'\0',len);
    memcpy(obj->e_attr.name,name,len);
    //*************************************************** */ 
    obj->e_attr.base = opt;
    //*************************************************** */ 
    slist_add_tail(pop_win.e_regist,&(obj->e_tail));
    //*************************************************** */

    
    return 0;
}

int pop_win_add(char * name,page_vtable_t *opt,void* user_para)
{
    int len = 0;
    pop_win_link_t * obj = NULL;

    if((!name)||(!opt)||(!pop_win.e_head)){
        l_e("para err\n");
        return -1;
    }

    obj = (pop_win_link_t *)psram_malloc(sizeof(pop_win_link_t));
    if(obj == NULL){
        l_e("obj err\n");
        return -1;
    }
    memset(obj, 0, sizeof(pop_win_link_t));
    slist_init(&(obj->e_tail));
    //**************************************************
    obj->e_attr.base = opt;
    obj->e_attr.user_data = user_para;
    //**************************************************
    len = strlen(name) + 1;
    obj->e_attr.name = (char *)psram_malloc(len);
    if(obj->e_attr.name == NULL){
        l_e("name err\n");
        psram_free(obj);
        obj = NULL;
        return -1;
    }
    memset(obj->e_attr.name,'\0',len);
    memcpy(obj->e_attr.name,name,len);
    //**************************************************
    lv_coord_t pw = 0;
    lv_coord_t ph = 0;

    pw = lv_disp_get_hor_res(NULL);
    ph = lv_disp_get_ver_res(NULL);

    obj->e_attr.root = lv_obj_create(lv_layer_top());
    lv_obj_set_pos(obj->e_attr.root,0,0);
    lv_obj_set_size(obj->e_attr.root,pw,ph);

	lv_obj_set_style_radius(obj->e_attr.root, 0, LV_PART_MAIN);
	lv_obj_set_style_border_width(obj->e_attr.root, 0, LV_PART_MAIN);
	lv_obj_set_style_border_color(obj->e_attr.root, lv_color_make(0x00, 0x00, 0x00), LV_PART_MAIN);
	lv_obj_set_style_border_opa(obj->e_attr.root, LV_OPA_0, LV_PART_MAIN);

	lv_obj_set_style_outline_width(obj->e_attr.root, 0, LV_PART_MAIN);
	lv_obj_set_style_shadow_width(obj->e_attr.root, 0, LV_PART_MAIN);
	lv_obj_set_scrollbar_mode(obj->e_attr.root, LV_SCROLLBAR_MODE_OFF);
	lv_obj_set_style_pad_all(obj->e_attr.root, 0,0);

    #if 0
    lv_obj_set_style_bg_opa(obj->e_attr.root,LV_OPA_0,0);
    #else
    lv_obj_set_style_bg_opa(obj->e_attr.root,LV_OPA_100,0);
    lv_obj_set_style_bg_color(obj->e_attr.root,lv_color_make(0,0,0),0);
    #endif

    lv_obj_add_flag(obj->e_attr.root,LV_OBJ_FLAG_HIDDEN);
    //**************************************************

    if(obj->e_attr.base->on_view_did_load)
    {
        l_e("e_attr=%x\n",&(obj->e_attr));
        l_e("root=%x\n",obj->e_attr.root);
        obj->e_attr.base->on_view_did_load(&obj->e_attr);
        obj->e_attr.base->on_custom_attr_config(&obj->e_attr);
        lv_obj_clear_flag(obj->e_attr.root,LV_OBJ_FLAG_HIDDEN);
        lv_obj_move_foreground(obj->e_attr.root);
    }   
    //**************************************************
    obj->e_attr.nav_bar = NULL;
    obj->e_attr.root_event_cb = NULL;
    obj->e_attr.manager = NULL;
    obj->e_attr.user_data = NULL;
    obj->e_attr.priv.req_enable_cache = 0;
    obj->e_attr.priv.req_disable_auto_cache = 0;
    obj->e_attr.priv.is_disable_auto_cache  = 0;
    obj->e_attr.priv.is_cached  = 0;
    obj->e_attr.priv.stash.ptr  = NULL;
    obj->e_attr.priv.stash.size = 0;
    obj->e_attr.priv.state      = 0;
    obj->e_attr.priv.anim.is_enter   = 0;
    obj->e_attr.priv.anim.is_busy    = 0;
    obj->e_attr.priv.anim.attr.type  = 0;
    obj->e_attr.priv.anim.attr.time  = 0;
    obj->e_attr.priv.anim.attr.path  = NULL;
    //**************************************************
    pop_win.len++;
    slist_add_tail(pop_win.e_head,&(obj->e_tail));
    //**************************************************

    return 0;
}

int pop_win_del(char * name)
{
	int ret = 0;
	slist_t* node;
	pop_win_link_t * obj = NULL;

    if(!name){
        return -1;
    }

    if(!pop_win.e_head)
        return -1;

	if(slist_isempty(pop_win.e_head)){
		l_e("list empty.\n");
		return -1;
	}

    //l_d("len=%d\n",pop_win.len);

	slist_for_each(node, (pop_win.e_head))
	{
		obj = slist_entry(node,pop_win_link_t,e_tail);
		if(obj){
            if(!strcmp(obj->e_attr.name,name)){
                ret = 1;
                break;
            }
		}
	}

	if(ret){
		slist_remove(pop_win.e_head, &(obj->e_tail));
		pop_win.len--;

        if(obj->e_attr.root){
            lv_obj_del(obj->e_attr.root);
            obj->e_attr.root = NULL;
        }

        if(obj->e_attr.user_data){
            psram_free(obj->e_attr.user_data);
            obj->e_attr.user_data = NULL;
        } 

        if(obj){
            psram_free(obj);
            obj = NULL;
        }
	}

	return 0;
}

int pop_win_trav(void)
{
	slist_t* node;
    pop_win_link_t * obj = NULL;

    if(!pop_win.e_head)
        return -1;
    //********************************************** */
	if(slist_isempty(pop_win.e_head)){
		l_e("list empty.\n");
		return -1;
	}
    //********************************************** */
    l_d("pop_len=%d\n",pop_win.len);
    //********************************************** */
	slist_for_each(node,(pop_win.e_head))
	{
		obj = slist_entry(node,pop_win_link_t,e_tail);
		if(obj){
			#if 1
			l_d("name=%s\n",obj->e_attr.name);
			#endif
		}
	}
    //********************************************** */

	return 0;
}

int pop_win_get_len(void)
{
    return pop_win.len;
}

pop_win_link_t * pop_win_get_by_index(int index)
{
    int len = 0;
	slist_t* node;
    pop_win_link_t * obj = NULL;

    if(!pop_win.e_head)
        return NULL;

	if(slist_isempty(pop_win.e_head)){
		l_e("list empty.\n");
		return NULL;
	}

	slist_for_each(node,(pop_win.e_head))
    {
		obj = slist_entry(node,pop_win_link_t,e_tail);
		if((obj)&&(len == index))
        {
            return obj;
		}
        len++;
	}

    //l_e("len=%d\n",len);

	return NULL;
}

pop_win_link_t *pop_win_get_by_name(const char * name)
{
    int i = 0;
    int ret = -1;
	slist_t* node;
    pop_win_link_t * obj = NULL;

    if(!name){
        l_e("name err\n");
        return NULL;
    }

    if(!pop_win.e_head){
        l_e("head err\n");
        return NULL;
    }

	if(slist_isempty(pop_win.e_head)){
		l_e("list empty.\n");
		return NULL;
	}
    //l_d("find name=%s\n",name);
	slist_for_each(node,(pop_win.e_head))
	{
		obj = slist_entry(node,pop_win_link_t,e_tail);
		if(obj)
        {
            ret = strcmp(obj->e_attr.name,name);
            if(!ret)
            {
                l_e("page [%s] find\n",name);
                return obj;
            }
		}
	}

	return NULL;
}

int pop_anim_config(lv_obj_t * obj,page_anim_attr_t attr)
{
    lv_anim_t anim;
    int32_t start = 0;
    int32_t end   = 0;

    lv_coord_t pw = LV_HOR_RES;
    lv_coord_t ph = LV_VER_RES;

    uint16_t           time    = attr.time;
    lv_anim_path_cb_t  path_cb = attr.path;
    lv_anim_exec_xcb_t xcb     = NULL;

    switch(attr.type){
    case LOAD_ANIM_GLOBAL:
    {
        return 0;
        break;
    }
    case LOAD_ANIM_OVER_LEFT:
    {

        break;
    }
    case LOAD_ANIM_OVER_RIGHT:
    {

        break;
    }
    case LOAD_ANIM_OVER_TOP:
    {

        break;
    }
    case LOAD_ANIM_OVER_BOTTOM:
    {

        break;
    }
    case LOAD_ANIM_MOVE_LEFT:
    {
        start = pw;
        end   = 0;
        xcb   = lv_obj_set_x;
        break;
    }
    case LOAD_ANIM_MOVE_RIGHT:
    {
        start = -pw;
        end   = 0;
        xcb   = lv_obj_set_x;
        break;
    }
    case LOAD_ANIM_MOVE_TOP:
    {
        start = ph;
        end   = 0;
        xcb   = lv_obj_set_y;
        break;
    }
    case LOAD_ANIM_MOVE_BOTTOM:
    {
        start = -ph;
        end   = 0;
        xcb   = lv_obj_set_y;
        break;
    }
    default:break;
    }

    lv_anim_init(&anim);
    lv_anim_set_var(&anim,obj);
    lv_anim_set_exec_cb(&anim,xcb);
    lv_anim_set_values(&anim,start,end);
    lv_anim_set_path_cb(&anim,path_cb);
    lv_anim_set_time(&anim,time);
    lv_anim_set_delay(&anim,50);
    lv_anim_start(&anim);

    return 0;
}

int pop_win_register(char* name,page_vtable_t *opt,void* user_para)
{
    int ret = -1;

    if(!name){
        return -1;
    }

    // if(pop_win.len >= pop_win.max_len){
    //     l_e("max 5\n");
    //     return -1;
    // }

    if(pop_win_get_by_name(name)){
        l_e("page [%s] already register\n",name);
        return -1;
    }
    //************************************************/
    ret = pop_win_add(name,opt,user_para);
    if(ret != 0){
        l_e("page install err\n");
        return -1;
    }

    return 0;
}

int pop_win_load(const char* name,page_vtable_t *opt,void* user_para)
{
    int ret = -1;
    int find_flag = 0;
    slist_t* node;
    pop_win_link_t * obj = NULL;
    //*********************************************************/
    if((!name)||(!opt)||(!pop_win.e_head)){
        l_e("para err\n");
        return NULL;
    }
    //*********************************************************/
	slist_for_each(node,(pop_win.e_head)){
		obj = slist_entry(node,pop_win_link_t,e_tail);
		if(obj){
            ret = strcmp(obj->e_attr.name,name);
            if(!ret){
                l_e("page [%s] find\n",name);
                find_flag = 1;
                lv_obj_move_foreground(obj->e_attr.root);
            }else{
                lv_obj_move_background(obj->e_attr.root);
            }
		}
	}
    //******************************************************** */
    if(find_flag){
        return 0;
    }

    pop_win_register(name,opt,user_para);
    lv_timer_reset(pop_win.time);

    return 0;
}

int pop_win_unload(void)
{
    pop_win_link_t * obj = NULL;
    page_vtable_t *  opt  = NULL;

    if((pop_win.len <= 0)||(!pop_win.e_head))
        return -1;

    //***************************************************** */
    //del old 
    obj = pop_win_get_by_index(pop_win.len-1);
    if(obj == NULL){
        l_d("obj err\n");
        return -1;
    }

    l_d("oldname:%s\n",obj->e_attr.name);
    //***************************************************** */
    opt = obj->e_attr.base;
    if(opt->on_view_did_unload)
    {
        opt->on_view_did_unload(&obj->e_attr);
    }
    pop_win_del(obj->e_attr.name);
    //******************************************************/
    //show new 
    obj = pop_win_get_by_index(pop_win.len-1);
    if(obj == NULL){
        l_d("obj err\n");
        return -1;
    }

    l_d("newname:%s\n",obj->e_attr.name);
    lv_obj_move_foreground(obj->e_attr.root);
    //******************************************************/


    return 0;
}
